package com.uzhie.util;


import com.uzhie.jt808.service.JT808ServiceImpl;
import com.uzhie.web.module.Catalog;
import com.uzhie.web.module.Vehicle;
import com.uzhie.web.module.base.Tree;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 树封装工具
 *
 * @param <T> 基于Tree的子类,便于进行树状算法迭代
 */
public class TreeUtil<T extends Tree> {

    JT808ServiceImpl service;

    private List<T> nodes;

    public TreeUtil(List<T> nodes) {
        this.nodes = nodes;
    }

    public TreeUtil(List<T> nodes, JT808ServiceImpl service) {
        this.nodes = nodes;
        this.service = service;
    }

    /**
     * 返回树状菜单
     *
     * @return
     */
    public List<T> buildTree() {
        List<T> list = new ArrayList<>();
        for (T node : nodes) {
            if (node.getParentId() == null) {
                list.add(node);
            }
        }
        list = getSortChildren(list);
        for (T node : list) {
            build(node);
        }
        return list;
    }

    /**
     * 通过有序的node list构建树结构,默认第一个节点为根节点
     *
     * @return
     */
    public List<T> buildTreeByTop() {
        List<T> list = new ArrayList<>();
        list.add(nodes.get(0));
        list = getSortChildren(list);
        for (T node : list) {
            build(node);
        }
        return list;
    }

    /**
     * 构建tree结构,
     *
     * @return
     */
    public List<T> buildCatalogTree() {
        List<T> list = new ArrayList<>();
        list.add(nodes.get(0));
        list = getSortChildren(list);
        for (T node : list) {
            build(node);
        }
        //合并树对象中的child与car节点
        for (T node : list) {
            marge(node);

        }
        return list;
    }

    /**
     * 构建tree结构,
     *
     * @return
     */
    public List<T> buildCatalogTreeNoCha() {
        List<T> list = new ArrayList<>();
        list.add(nodes.get(0));
        list = getSortChildren(list);
        for (T node : list) {
            build(node);
        }
        //合并树对象中的child与car节点
        for (T node : list) {
            marge2(node);
        }
        return list;
    }

    /***
     * 构建权限树
     *
     * @param node
     * @Title: build
     */
    private void build(T node) {
        List<T> children = getChildren(node);
        if (!children.isEmpty()) {
            node.setChildren((List<Tree>) children);
            for (T child : children) {
                build(child);
            }
        } else {
            node.setOpen(false);
        }
    }

    /**
     * @param node
     * @return
     * @Title: getChildren
     * @Description: TODO 获取子节点
     */
    private List<T> getChildren(T node) {
        List<T> children = new ArrayList<>();
        String id = node.getId();
        for (T child : nodes) {
            child.setmLevel(child.getLevel());
            if (id.equals(child.getParentId())) {
                children.add(child);
            }
        }
        return getSortChildren(children);
        // return children;
    }

    /**
     * @param children
     * @return
     * @Title: getChildren
     * @Description: TODO 获取排序子节点
     */
    private List<T> getSortChildren(List<T> children) {
//        MyCompare my = new MyCompare();
//        Collections.sort(children, my);
        Collections.sort(children, Comparator.comparing(T::getLevel));
        return children;
    }

    private T marge(T node) {
        if (node.getChildren() != null && node.getChildren().size() > 0) {
            for (Tree child : node.getChildren()) {
                marge((T) child);
            }
        }
        if (node.getCars() != null && node.getCars().size() > 0) {
            for (Vehicle vehicle : node.getCars()) {
                vehicle.setType("99");
                List<Tree> catalogs = new ArrayList<>();
                for (int channel = 1; channel <= vehicle.getVideoNumber(); channel++) {
                    Catalog catalog = new Catalog();
                    catalog.setId(channel + "");
                    catalog.setName("通道" + channel);
                    catalog.setType("98");
                    catalog.setIcon("../../../images/channel.png");
                    catalog.setOpen(false);
                    catalogs.add(catalog);
                }
                vehicle.setOpen(false);
                vehicle.setChildren(catalogs);
                if (vehicle.getSimNumber() != null && service != null)
                    vehicle.setOnline(service.isOnline(vehicle.getSimNumber()));
                if (vehicle.isOnline()) {
                    vehicle.setName(vehicle.getName() + "[在线]");
                    vehicle.setIcon("../../../images/car_on.png");
                } else {
                    vehicle.setName(vehicle.getName() + "[不在线]");
                    vehicle.setIcon("../../../images/car_off.png");
                }
            }
            if (node.getChildren() == null) node.setChildren(new ArrayList<Tree>());
            node.getChildren().addAll(node.getCars());
            node.setCars(null);
        }
        return node;
    }

    private T marge2(T node) {
        if (node.getChildren() != null && node.getChildren().size() > 0) {
            for (Tree child : node.getChildren()) {
                marge2((T) child);
            }
        }
        if (node.getCars() != null && node.getCars().size() > 0) {
            for (Vehicle vehicle : node.getCars()) {
                vehicle.setType("99");
                vehicle.setOpen(false);
            }
            if (node.getChildren() == null) node.setChildren(new ArrayList<Tree>());
            node.getChildren().addAll(node.getCars());
            node.setCars(null);
        }
        return node;
    }

    /**
     * 内部排序器
     */
    public class MyCompare implements Comparator<T> {

        @Override
        public int compare(T o1, T o2) {
            if (o1.getLevel() < o2.getLevel()) {
                return -1;
            } else {
                return 1;
            }
        }

    }
}